package com.springbootblog.controller.fontend.thread.async;

/**
 * 取钱线程不安全
 */
public class TestAsyncTwo
{
    public static void main(String[] args) {
        // 创建一个账户
        Account  account = new Account(100, "marray");
        // 第一个取钱人
        Bank you = new Bank(account, 50);
        // 第二个取钱人
        Bank wife = new Bank(account, 100);
        // 开始取钱
        new Thread(you, "you").start();
        // 开始曲线
        new Thread(wife, "wife").start();
    }
}

/**
 * 银行类，模拟取款
 */
class Bank implements Runnable
{
    // 账户
    private Account account;
    // 取了多少钱
    private int getMoney;
    // 拥有多少钱
    private int haveMoney;

    public Bank(Account account, int getMoney)
    {
        this.account = account;
        this.getMoney = getMoney;
    }
    @Override
    public void run()
    {
        draw();
    }

    /**
     * 取钱方法：
     * synchronized 锁的是this
     */
    public void draw()
    {
        /**
         * 这里我们要锁定的是银行账户，而非方法
         */
        synchronized(account)
        {
            // 延迟线程，放大问题
            try {
                Thread.sleep(1000);
            } catch ( InterruptedException e) {
                throw new RuntimeException(e);
            }
            // 判断账户余额
            if(account.money - getMoney < 0)
            {
                System.out.println("You account is not enough! ");
            }
            else
            {
                System.out.println("account.money："+account.money);
                System.out.println("getMoney："+getMoney);
                // 取钱
                account.money = account.money - getMoney;
                System.out.println("account is shengyu: "+ account.money);
                // 加钱
                haveMoney = haveMoney + getMoney;
                System.out.println(Thread.currentThread().getName() +" haveMoney is "+haveMoney);
            }
        }

    }

}

/**
 * 账户类
 */
class Account
{
    Integer money = 0;
    private String name = "";
    public Account(Integer money, String name)
    {
        this.money = money;
        this.name = name;
    }
}



